{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a9f8c081-1548-4247-83d9-82d01f355808",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sisl as si\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1cb92c41-a795-4cf6-93b3-f9e7431a944e",
   "metadata": {},
   "source": [
    "# Reading/writing geometries\n",
    "\n",
    "`sisl` provides an interface for various electronic structure codes as well as commonly found data standards.\n",
    "\n",
    "------\n",
    "\n",
    "In this tutorial we will create some geometries, write them in various formats, and re-read them in."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "00a3fd65-a0a1-407f-8a69-50a3f53b38b2",
   "metadata": {},
   "outputs": [],
   "source": [
    "BN = si.geom.bilayer(1.42, si.Atom(\"N\"), si.Atom(\"B\"))\n",
    "print(BN)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f582b010-df90-45b4-a765-65ed0ad11c9c",
   "metadata": {},
   "source": [
    "We will now write this geometry out into a common `xyz` file format. This file-format is easily parseable by a large number of other codes (including being compatible with the [ASE](https://wiki.fysik.dtu.dk/ase/) format)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "de0dd680-8c54-4b54-85ce-a9e638a9fc4c",
   "metadata": {},
   "outputs": [],
   "source": [
    "BN.write(\"BN.xyz\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97dd3c7a-fdc2-4098-8200-b4a0f3ccb063",
   "metadata": {},
   "source": [
    "By now there should be a file called `BN.xyz` in the current directory.\n",
    "\n",
    "----\n",
    "\n",
    "Let us try and read it in again, to check it retains the same properties. There are various ways to do this:\n",
    "- `si.io.get_sile(filename).read_geometry()`\n",
    "- `si.Geometry.read(filename)` will internally do as above\n",
    "- `si.Geometry.new(filename)`, this last method is the most versatile method as it can also work on Python objects   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d3174792-41ad-4f0b-b377-41ff8d8076af",
   "metadata": {},
   "outputs": [],
   "source": [
    "BN2 = si.Geometry.new(\"BN.xyz\")\n",
    "assert BN2 == BN"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1aa59549-2774-4fd8-bce9-82db22d83690",
   "metadata": {},
   "source": [
    "For a larger interaction with the file content, say if the file contains both geometries and real space quantities, it can be benificial to store the file handle. In sisl, files are called `Sile`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df54e92a-3703-4e12-9b89-8c4591621e4b",
   "metadata": {},
   "outputs": [],
   "source": [
    "xyz = si.io.get_sile(\"BN.xyz\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a9d3aed-7443-4419-87b2-7adf1bf33145",
   "metadata": {},
   "source": [
    "Now first read the `Lattice`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "070ece0a-c6c9-4be8-b751-b75be2e315c9",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(xyz.read_lattice())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ce75ebb-cb67-4707-8674-39c86cdc8228",
   "metadata": {},
   "source": [
    "And then read the `Geometry`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4265af26-93b0-433d-9893-6e709ef4aa89",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(xyz.read_geometry())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9aff7883-4230-4025-af06-edb7b5345a39",
   "metadata": {},
   "source": [
    "## Other file formats\n",
    "\n",
    "There are a broad range of file formats. To automatically write out into the Siesta XV file format, simply do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ffa649fe-2cf0-4dd3-9e1e-90312815de25",
   "metadata": {},
   "outputs": [],
   "source": [
    "BN.write(\"BN.XV\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "545cc7c7-30b5-40a9-8e48-992171ba03f1",
   "metadata": {},
   "source": [
    "One cannot expect all file-formats to retain all information in a geometry. For instance the `xyz` file format does not specify how orbitals should be described. Therefore orbital information will be lost when writing to the `xyz` file format, see for instance here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf8637a6-92b4-4ff9-b48a-6d1c736b45a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "BN2 = si.geom.bilayer(1.42, si.Atom(\"N\", [1, 2]), si.Atom(\"B\", [2, 3]))\n",
    "print(BN2.atoms)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab9471f8-554b-4b85-bed5-e0668d233b3d",
   "metadata": {},
   "source": [
    "Note how the two atoms has multiple orbitals, with different orbital ranges."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7936874e-d81e-42c3-9f5f-62f423012f5a",
   "metadata": {},
   "outputs": [],
   "source": [
    "BN2.write(\"BN2.xyz\")\n",
    "print(si.Geometry.new(\"BN2.xyz\").atoms)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2eaa066-f2ae-4868-a4fa-5016f81bfd53",
   "metadata": {},
   "source": [
    "Here we extracted only the atoms object to show the difference there."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c8946342-6db1-4496-9408-f8484b96d828",
   "metadata": {},
   "source": [
    "### Selecting origin of the output\n",
    "\n",
    "`sisl` implements a variety of objects that interacts with the `stdout` of codes. For instance:\n",
    "```shell\n",
    "# Regular siesta out\n",
    "siesta RUN.fdf > RUN.out\n",
    "# VASP out\n",
    "vasp > RUN.out\n",
    "...\n",
    "```\n",
    "In general the extensions are not well-defined and there is a high probability of overlapping extensions with different codes.\n",
    "To make it simpler for the user to use the correct object for a file, one can specify a name of the code origin:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f5d56e9-36a4-4b27-b168-dfdcb3824f1c",
   "metadata": {},
   "outputs": [],
   "source": [
    "siesta_out = si.get_sile(\"RUN.out{siesta}\")\n",
    "vasp_out = si.get_sile(\"RUN.out{vasp}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
